home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ABUSESRC.ZIP
/
AbuseSrc
/
macabuse
/
imlib
/
readwav.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-20
|
4KB
|
169 lines
#include "readwav.hpp"
#include "specs.hpp"
#include "macs.hpp"
#include "dprint.hpp"
struct wav_chunk
{
char id[4];
unsigned long size;
char type[4];
} ;
struct wav_tag
{
char id[4];
unsigned long size;
} ;
struct wav_format
{
unsigned short fmt_tag,channels;
unsigned long samplesps,avg_bytesps;
unsigned short align;
} ;
struct pcm_wave
{
wav_format wf;
unsigned short bitsps;
} ;
void read_chunk(wav_chunk &chunk, bFILE *fp)
{
fp->read(&chunk.id,4);
chunk.size=fp->read_long();
fp->read(&chunk.type,4);
}
void read_tag(wav_tag &tag, bFILE *fp)
{
fp->read(&tag.id,4);
tag.size=fp->read_long();
}
void read_wav_format(wav_format &fmt, bFILE *fp)
{
fmt.fmt_tag=fp->read_short();
fmt.channels=fp->read_short();
fmt.samplesps=fp->read_long();
fmt.avg_bytesps=fp->read_long();
fmt.align=fp->read_short();
}
void read_pcm(pcm_wave &pcm, bFILE *fp)
{
read_wav_format(pcm.wf,fp);
pcm.bitsps=fp->read_short();
}
void write_wav(char *filename, long sample_rate, long data_size, unsigned char *data)
{
wav_chunk chunk;
wav_tag tag;
pcm_wave pcm;
bFILE *fp=open_file(filename,"wb");
if (fp->open_failure())
{
dprintf("Unable to open %s for writing\n");
delete fp;
exit(1);
}
/*************** Write the chunk ***************************/
fp->write("RIFF",4);
fp->write_long(data_size+36);
fp->write("WAVE",4);
/************** Write the tag *******************************/
fp->write("fmt ",4);
fp->write_long(16);
/************** Write PCM ***********************************/
fp->write_short(1); // format_tag
fp->write_short(1); // mono recording
fp->write_long(sample_rate);
fp->write_long(sample_rate); // average bytes per sec
fp->write_short(1); // allignment? Don't know what this does?
fp->write_short(8); // 8 bits per sample
/************* Write data tag ******************************/
fp->write("data",4);
fp->write_long(data_size);
/************ Now write sample data ************************/
fp->write(data,data_size);
delete fp;
}
unsigned char *read_wav(char *filename, long &sample_rate, long &data_size)
{
unsigned char *data;
wav_chunk chunk;
wav_tag tag;
pcm_wave pcm;
bFILE *fp=open_file(filename,"rb");
if (fp->open_failure())
{ delete fp; return NULL; }
read_chunk(chunk,fp);
if (memcmp(chunk.type,"WAVE",4)!=0)
{
dprintf("Bad WAV file (chunk) %s\n",filename);
delete fp;
return NULL;
}
read_tag(tag,fp);
if (memcmp(tag.id,"fmt ",4)!=0)
{
dprintf( "fmt tag missing, bad file (%s)\n",filename);
delete fp;
return NULL;
}
read_pcm(pcm,fp);
fp->seek(tag.size-16,SEEK_CUR); // seek to offset of sample
read_tag(tag,fp);
if (memcmp(tag.id,"data",4)!=0)
{
dprintf("Bad Wav file (tag), %s\n",filename);
delete fp;
return NULL;
}
data_size=tag.size;
data=(unsigned char *)jmalloc(tag.size,"WAV data");
ERROR(data,"Malloc error");
sample_rate=pcm.wf.samplesps;
ERROR(fp->read(data,tag.size)==tag.size,"Premature end of file");
ERROR(pcm.bitsps==8,"Only 8-bit samples supported");
ERROR(pcm.wf.channels==1,"Only mono samples supported");
ERROR(pcm.wf.align==1,"Bad block allignment");
delete fp;
return data;
}